package com.kylin.factorymethod.a;

/**
 * 针对于简单工厂的问题
 * 修改代码如下，使用简单工厂方法模式
 */


//抽象产品
interface Food {
    void eat();
}

//具体产品
class Hamburger implements Food {

    @Override
    public void eat() {
        System.out.println("吃汉堡包");
    }
}

class RiceNoodle implements Food {

    @Override
    public void eat() {
        System.out.println("过桥米线");
    }
}

interface FoodFactory {
    Food getFood();

}

class HamburgerFactory implements FoodFactory {

    @Override
    public Food getFood() {
        return new Hamburger();
    }
}

class RiceNoodleFactory implements FoodFactory {

    @Override
    public Food getFood() {
        return new RiceNoodle();
    }
}

class Business {
    public static void taste(FoodFactory foodFactory) {
        Food food = foodFactory.getFood();
        System.out.println("评委1，品尝");
        food.eat();

        Food food2 = foodFactory.getFood();
        System.out.println("评委2，品尝");
        food2.eat();

        Food food3 = foodFactory.getFood();
        System.out.println("评委3，品尝");
        food3.eat();
    }

}

//-------------------------------------------------------
class Lp implements Food {

    @Override
    public void eat() {
        System.out.println("从小就吃凉皮");
    }
}

class LpFactory implements FoodFactory {

    @Override
    public Food getFood() {
        return new Lp();
    }
}

public class AppTest {
    public static void main(String[] args) {
        FoodFactory foodFactory = new HamburgerFactory();

        Business.taste(foodFactory);
    }
}


/**
 * 工厂方法
 * 优点：
 * 1.仍然具有简单工厂的优点，服务器修改了具体产品的类名以后，客户端不知道
 * 2.当客服端需要扩展一个新的产品时，不需要修改作者原来的代码，只是扩展一个新的工厂而已！
 * <p>
 * 杠点：
 * 1.我们已经知道，简单工厂也好，工厂方法也好，都有一个优点，就是服务器端的具体产品类名变化了以后，客户端不知道！
 * 但是，反观我们现在的代码，客户端仍然依赖具体的工厂的类名呀！此时，如果服务器修改了具体工厂的类名，那么客户端也要随之一起修改！
 * 感觉折腾了一圈，又回到了原点
 * <p>
 * 解释：
 * 工厂的名字，时视为接口的。作者有责任，有义务，保证工厂的名字是稳定的，也就是说，虽然客户端依赖于工厂的具体类名，可是在IT业内，
 * 所有工厂的名字都是趋向于稳定的（并不是100稳定不会变）。只是工厂类的名字，要比具体产品类的名字更加稳定
 * <p>
 * 2.既然产品是我们自己客户端扩展出来的，那么为什么不直接自己实例化呢？毕竟这个扩展出来的Lp这个产品，我们自己就是作者。我们想怎么改类名自己
 * 都能把控！为什么还要为自己制作的产品做工厂呢？
 * <p>
 * 解释：
 * 因为，作者在开发功能是，不仅仅只会开发处一些抽象产品，具体产品，对应的工厂，还会配置地搭配一些提前做好的框架。
 * <p>
 * 缺点：
 * 如果有多个产品等级，那么工厂类的数量，就会爆炸式增长！
 */
